﻿/**
 * Copyright (C) 2012 - present by Privosoft LLC. 
 * 
 * Please see distribution for license.
 */
using System;
using System.Configuration;
using System.Data;
using System.Windows.Forms;
using System.Data.SqlClient;
using System.Collections.Generic;
using System.Linq;

namespace Privosoft.DataFrame.UI
{
    public partial class Form1 : Form
    {
        internal static string DbSchema
        {
            get { return ConfigurationManager.AppSettings["dbschema"]; }
        }
        public Form1()
        {
            InitializeComponent();
            treeView1.NodeMouseDoubleClick += treeView1_NodeMouseDoubleClick;
            treeView1.NodeMouseClick += treeView1_NodeMouseClick;
        }

        void treeView1_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e)
        {
            if (e.Node.Tag != null)
            {
                int id = (int)e.Node.Tag;
                var dataFrameInfo = LoadDataFrameInfo(id);                
                

                var table = new DataTable();
                table.Columns.Add("Property Name");
                table.Columns.Add("Property Value");

                if (dataFrameInfo.Properties != null)
                    foreach(var kv in dataFrameInfo.Properties)
                        table.Rows.Add(kv.Key, kv.Value);

                dgvProps.DataSource = table;                
            }
        }

        void treeView1_NodeMouseDoubleClick(object sender, TreeNodeMouseClickEventArgs e)
        {
            if (e.Node.Tag != null)
            {
                int id = (int)e.Node.Tag;
                // prompt user if wants to load the dataframe
                if (MessageBox.Show(this, "Load data frame [" + id + @"]?", "Load Confirmation", MessageBoxButtons.OKCancel, MessageBoxIcon.Question)
                    == DialogResult.OK)
                {
                    // load the data frame (extract the id from the clicked node)
                    LoadDataFrame(id);
                }
            }
        }

        private DataFrameInfo LoadDataFrameInfo(int id)
        {
            using (SqlConnection cn = new SqlConnection(Properties.Settings.Default.DBConnectionString))
            {
                cn.Open();
                using (var loader = new DbContext(cn, DbSchema))
                {
                    var info = loader.GetDataFrameInfos().Where(i => i.Id == id).FirstOrDefault();
                    return info;
                }
            }
        }

        private void LoadDataFrame(int id)
        {
            using (SqlConnection cn = new SqlConnection(Properties.Settings.Default.DBConnectionString))
            {
                cn.Open();
                using (var loader = new DbContext(cn, DbSchema))
                {
                    
                    var sw = System.Diagnostics.Stopwatch.StartNew();

                    var dt = loader.GetDataFrameById(id);
                    sw.Stop();
                    System.Diagnostics.Debug.WriteLine(
                        string.Format("button1_Click: getDataFrameById took {0:0.0} secs.", sw.ElapsedMilliseconds / 1000.0));
                    sw.Reset();
                    sw.Start();
                    dataGrid.DataSource = dt;
                    sw.Stop();
                    System.Diagnostics.Debug.WriteLine(
                        string.Format("button1_Click: Binding data to grid took {0:0.0} secs.", sw.ElapsedMilliseconds / 1000.0));

                }
            }
        }

        private void Form1_Shown(object sender, EventArgs e)
        {
            LoadSchemaInfo();
        }

        private void LoadSchemaInfo()
        {
            treeView1.Nodes.Clear();
            using (var db = new DbContext(new SqlConnection(Properties.Settings.Default.DBConnectionString), DbSchema))
            {
                var schemas = db.GetSchemas(true);
                var frameInfos = db.GetDataFrameInfos();

                var mainNode = new TreeNode("Schemas");
                foreach (var schemaInfo in schemas)
                {
                    var s = schemaInfo;
                    // SCHEMA top level tree-node
                    var tn = new TreeNode(s.Name);
                    mainNode.Nodes.Add(tn);
                    // SCHEMA Columns tree-node
                    var columnChildNodes = new List<TreeNode>();
                    foreach (var col in s.Columns)
                    {
                        var tnc = new TreeNode(string.Format("[{0}] {1} : {2}", col.Id, col.Name, col.DataType));
                        columnChildNodes.Add(tnc);
                    }
                    // SCHEMA COLUMNS Parent tree-node
                    tn.Nodes.Add( new TreeNode("Columns", columnChildNodes.ToArray()) );

                    // DATAFRAME child tree-nodes
                    var frameTreeNodes = new List<TreeNode>();
                    var matchingFrames = frameInfos.Where(f => f.Schema.Id == s.Id);
                    foreach (var df in matchingFrames.OrderByDescending(f => f.CreatedTimestamp))
                    {
                        if (df != null)
                        {
                            var tnf = new TreeNode(
                                    string.Format("[{0}] Rows = {1}, {2}, {3}",
                                                    df.Id, df.RowCount, df.CreatedTimestamp.ToString("yyyy-MM-dd HH:mmm:ss"), df.Username)
                                    ) {Tag = df.Id};
                            frameTreeNodes.Add(tnf);
                        }
                    }
                    // DATAFRAME info Parent tree-node
                    tn.Nodes.Add(new TreeNode("Frames", frameTreeNodes.ToArray()));
                }
                treeView1.Nodes.Add(mainNode);
                mainNode.Expand();
            }
        }

        private void toolStripButton1_Click(object sender, EventArgs e)
        {
            // show load data dialog
            var frm = new ImportDataForm();
            frm.Show();
        }

        private void toolStripButton3_Click(object sender, EventArgs e)
        {
            // refresh schema browser data
            LoadSchemaInfo();
        }
    }
}
